package com.yang.test.service.serviceImpl;

import com.yang.test.domain.*;
import com.yang.test.domain.VO.QuestionVO;
import com.yang.test.domain.VO.ResultMVO;
import com.yang.test.domain.VO.TestQuestionsVO;
import com.yang.test.mapper.MbtiMapper;
import com.yang.test.service.DeepseekService;
import com.yang.test.service.MbtiService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
public class MbtiServiceImpl implements MbtiService {

    @Autowired
    private MbtiMapper mbtiMapper;

    @Autowired
    private DeepseekService deepseekService;

    @Override
    public TestQuestionsVO getTestQuestions(String testId) {
        // 获取测试信息
        Test test = mbtiMapper.getTestById(testId);
        if (test == null) {
            return null;
        }

        // 获取测试的所有问题
        List<Question> questions = mbtiMapper.getQuestionsByTestId(testId);
        if (questions == null || questions.isEmpty()) {
            return null;
        }

        // 获取所有问题ID
        List<Integer> questionIds = questions.stream()
                .map(Question::getId)
                .collect(Collectors.toList());

        // 批量获取所有选项
        List<Option> allOptions = mbtiMapper.getOptionsByQuestionIds(questionIds);

        // 按问题ID对选项进行分组
        Map<Integer, List<Option>> optionsByQuestionId = allOptions.stream()
                .collect(Collectors.groupingBy(Option::getQuestionId));

        // 构建返回结果
        List<QuestionVO> questionVOList = new ArrayList<>();
        for (Question question : questions) {
            QuestionVO questionVO = new QuestionVO();
            questionVO.setId(question.getId());
            questionVO.setName(question.getName());
            questionVO.setType(question.getType());
            questionVO.setInfoname(test.getName());
            questionVO.setOption(optionsByQuestionId.getOrDefault(question.getId(), new ArrayList<>()));
            questionVOList.add(questionVO);
        }

        TestQuestionsVO result = new TestQuestionsVO();
        result.setId(test.getId());
        result.setName(test.getName());
        result.setList(questionVOList);

        return result;
    }

    @Override
    public String processAnswers(Map<String, Integer> answers, String testType) {
        // 计算MBTI维度得分
        Map<String, Double> scores = calculateScores(answers);

        // 生成结果ID
        String resultId = generateResultId();

        // 根据得分确定MBTI类型
        String mbtiType = determineMbtiType(scores);
        log.info("计算得到MBTI类型: {}, 得分: {}", mbtiType, scores);

        // 生成维度数据
        List<Dimension> dimensions = generateDimensions(answers);

        // 生成个性化报告
        String report = deepseekService.generateReport(mbtiType, dimensions);

        // 创建结果对象
        ResultM result = new ResultM();
        result.setId(resultId);
        result.setType(mbtiType);
        result.setDimensions(dimensions);
        result.setReport(report);
        result.setCreatedAt(new Date());

        // 保存结果到数据库
        int rows = mbtiMapper.saveResult(result);
        log.info("结果保存完成, 影响行数: {}", rows);

        return resultId;
    }

    @Override
    public ResultMVO getResult(String resultId) {
        ResultM result = mbtiMapper.getResultById(resultId);

        if (result == null) {
            return null;
        }

        // 转换为视图对象
        ResultMVO resultMVO = new ResultMVO();
        resultMVO.setId(result.getId());
        resultMVO.setType(result.getType());
        resultMVO.setDimensions(result.getDimensions());
        resultMVO.setReport(result.getReport());

        return resultMVO;
    }

//    @Override
//    public Object getResult(String resultId) {
//        // 实现获取结果的逻辑
//        return mbtiMapper.getResultById(resultId);
//    }

    /**
     * 计算MBTI维度得分
     */
    @Override
    public Map<String, Double> calculateScores(Map<String, Integer> answers) {
        // 在此示例中，我们直接将原始分数作为得分，因为输入已经是每个维度的得分
        return Map.of(
                "E", (double) answers.getOrDefault("E", 0),
                "I", (double) answers.getOrDefault("I", 0),
                "S", (double) answers.getOrDefault("S", 0),
                "N", (double) answers.getOrDefault("N", 0),
                "T", (double) answers.getOrDefault("T", 0),
                "F", (double) answers.getOrDefault("F", 0),
                "J", (double) answers.getOrDefault("J", 0),
                "P", (double) answers.getOrDefault("P", 0)
        );
    }

    /**
     * 根据得分确定MBTI类型
     */
    @Override
    public String determineMbtiType(Map<String, Double> scores) {
        String attitude = scores.get("E") >= scores.get("I") ? "E" : "I";
        String perception = scores.get("S") >= scores.get("N") ? "S" : "N";
        String judgment = scores.get("T") >= scores.get("F") ? "T" : "F";
        String lifestyle = scores.get("J") >= scores.get("P") ? "J" : "P";

        return attitude + perception + judgment + lifestyle;
    }

    /**
     * 生成维度数据
     */
    private static List<Dimension> generateDimensions(Map<String, Integer> scores) {
        List<Dimension> dimensions = new ArrayList<>();

        dimensions.add(normalizeDimension("E", "I", scores));
        dimensions.add(normalizeDimension("S", "N", scores));
        dimensions.add(normalizeDimension("T", "F", scores));
        dimensions.add(normalizeDimension("J", "P", scores));

        return dimensions;
    }

    /**
     * 归一化并生成单个维度的数据
     */
    private static Dimension normalizeDimension(String left, String right, Map<String, Integer> scores) {
        int leftScore = scores.getOrDefault(left, 0);
        int rightScore = scores.getOrDefault(right, 0);

        double total = leftScore + rightScore;

        long leftValue = Math.round((leftScore / total) * 100);
        long rightValue = Math.round((rightScore / total) * 100);

        // 确保总和为100
        if (leftValue + rightValue != 100) {
            if (leftValue > rightValue) {
                leftValue = 100 - rightValue;
            } else {
                rightValue = 100 - leftValue;
            }
        }

        return new Dimension(left, right, leftValue, rightValue);
    }

    private String generateResultId() {
        return "result_" + Instant.now().toEpochMilli();
    }
}